
#include "EvURI.h"
#include "ErrorCode.h"
#include <event2/http.h>
#include <event2/util.h>
#include <assert.h>

#define get_safe_string(x, y) (x) ? (x) : (y)

int EvURI::get_default_port(const char* schem)
{
    if (schem == nullptr) {
        return 0;
    }
    if (evutil_ascii_strcasecmp(schem, "http") == 0 || evutil_ascii_strcasecmp(schem, "ws") == 0) {
        return 80;
    }
    else if (evutil_ascii_strcasecmp(schem, "https") == 0 || evutil_ascii_strcasecmp(schem, "wss") == 0) {
        return 443;
    }
    else if (evutil_ascii_strcasecmp(schem, "smtp") == 0) {
        return 25;
    }
    else if (evutil_ascii_strcasecmp(schem, "smtps") == 0) {
        return 465;
    }
    else if (evutil_ascii_strcasecmp(schem, "ftp") == 0) {
        return 21;
    }
    else if (evutil_ascii_strcasecmp(schem, "gopher") == 0) {
        return 70;
    }
    else if (evutil_ascii_strcasecmp(schem, "ldap") == 0) {
        return 389;
    }
    else if (evutil_ascii_strcasecmp(schem, "nntp") == 0) {
        return 119;
    }
    else if (evutil_ascii_strcasecmp(schem, "snews") == 0) {
        return 563;
    }
    else if (evutil_ascii_strcasecmp(schem, "imap") == 0) {
        return 143;
    }
    else if (evutil_ascii_strcasecmp(schem, "pop") == 0) {
        return 110;
    }
    else if (evutil_ascii_strcasecmp(schem, "sip") == 0) {
        return 5060;
    }
    else if (evutil_ascii_strcasecmp(schem, "rtsp") == 0) {
        return 554;
    }
    else if (evutil_ascii_strcasecmp(schem, "prospero") == 0) {
        return 191;
    }
    else if (evutil_ascii_strcasecmp(schem, "nfs") == 0) {
        return 2049;
    }
    else if (evutil_ascii_strcasecmp(schem, "tip") == 0) {
        return 3372;
    }
    else if (evutil_ascii_strcasecmp(schem, "acap") == 0) {
        return 674;
    }
    else if (evutil_ascii_strcasecmp(schem, "telnet") == 0) {
        return 23;
    }
    else if (evutil_ascii_strcasecmp(schem, "ssh") == 0) {
        return 22;
    }

    return 0;
}


EvURI::~EvURI()
{
    if (uri_) {
        evhttp_uri_free(uri_);
    }
}

std::error_code EvURI::parse_from_string(const std::string& uriStr)
{
    if (uri_) {
        evhttp_uri_free(uri_);
    }
    uri_ = evhttp_uri_parse(uriStr.c_str());
    if (uri_ == nullptr) {
        return make_custom_error_code(custom_error::invalid_uri);
    }

    schem_ = get_safe_string(evhttp_uri_get_scheme(uri_), "");
    userinfo_ = get_safe_string(evhttp_uri_get_userinfo(uri_), "");
    host_ = get_safe_string(evhttp_uri_get_host(uri_), "");
    port_ = evhttp_uri_get_port(uri_);
    if (port_ == -1) {
        port_ = get_default_port(schem_.c_str());
    }
    path_ = get_safe_string(evhttp_uri_get_path(uri_), "/");
    query_ = get_safe_string(evhttp_uri_get_query(uri_), "");
    fragment_ = get_safe_string(evhttp_uri_get_fragment(uri_), "");

    return std::error_code();
}


#undef get_safe_string